#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define NUM 1024

struct MyFILE
{
    int fd;
    char buffer[NUM];
    int end; // 缓冲区结尾
};

typedef struct MyFILE MyFILE;

MyFILE* fopen_(const char* pathname, const char* mode)
{
    assert(pathname);
    assert(mode);
    MyFILE *fp = NULL;
    if (strcmp(mode, "r") == 0)
    {

    }
    else if (strcmp(mode, "r+") == 0)
    {

    }
    else if (strcmp(mode, "w") == 0)
    {
        int fd = open(pathname, O_CREAT | O_TRUNC | O_WRONLY, 0666);
        if (fd >= 0)
        {
            fp = (MyFILE*)malloc(sizeof (MyFILE));
            memset(fp, 0, sizeof (MyFILE));
            fp->fd = fd;
        }   
    }
    else if (strcmp(mode, "w+") == 0)
    {

    }
    else if (strcmp(mode, "a") == 0)
    {

    }
    else if (strcmp(mode, "a+") == 0)
    {

    }
    else {}
    return fp;
}

void fputs_(const char* message, MyFILE* fp)
{
    assert(message);
    assert(fp);

    strcpy(fp->buffer + fp->end, message);
    fp->end += strlen(message);

    if (fp->fd == 0)
    {
        // 标准输入
    }
    else if (fp->fd == 1)
    {
        // 标准输出
        if (fp->buffer[fp->end] == '\n')
        {
            write(fp->fd, fp->buffer, fp->end);
            fp->end = 0;
        }
    }
    else if (fp->fd == 2)
    {
        // 标准错误
    }
    else 
    {
        // 其他文件
    }
}

void fflush_(MyFILE* fp)
{
    assert(fp);

    if (fp->end != 0)
    {
        // 把数据写到了内核
        write(fp->fd, fp->buffer, fp->end);
        syncfs(fp->fd); // 将数据写入到磁盘
    }
}

void fclose_(MyFILE* fp)
{
    assert(fp);

    fflush_(fp);
    close(fp->fd);
}


int main()
{
    MyFILE* fp = fopen_("./log.txt", "w");
    if (fp == NULL)
    {
        printf("open file error\n");
        return 1;
    }

    fputs_("hello world\n", fp);

    fclose_(fp);

    return 0;
}


//int main()
//{
//    // C语言
//    printf("hello printf\n");
//    fprintf(stdout, "hello fprintf\n");
//    const char* s = "hello fputs\n";
//    fputs(s, stdout);
//
//    // 系统接口
//    const char*ss = "hello write\n";
//    write(1, ss, strlen(ss));
//
//    // 创建子进程
//    fork();
//    return 0;
//}
